package it.intecs.pisa.smarcos.activities;

import it.intecs.pisa.smarcos.R;
import it.intecs.pisa.smarcos.base.ConfigurationManager;
import it.intecs.pisa.smarcos.base.GestureIntents;
import it.intecs.pisa.smarcos.base.KeyboardsView;
import it.intecs.pisa.smarcos.base.SpeechManager;
import it.intecs.pisa.smarcos.util.ContextUtils;
import it.intecs.pisa.smarcos.util.MathUtils;
import it.intecs.pisa.smarcos.util.PatternUtils;

import java.util.ArrayList;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.inputmethodservice.Keyboard;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.ViewGroup;


public class Keyboards extends BaseActivity { //implements OnKeyboardActionListener {
	
	public static final String INTENT_SHOW="it.intecs.pisa.smarcos.activities.Keyboards.SHOW";
	private static final String TAG = Keyboards.class.getSimpleName();
	private static final int MODIFY_FLAG = 0;
	private static final int BACK_TO_QWERTY = 1;

	private SpeechManager speechManager;
	private ConfigurationManager configurationManager;
	
	int backTo = 0;
	private Boolean flag = false;
	private String position;
	private String whichKeyboard;
	private String messageToSay;
	private String returnHere;
	private String currentText="";
	private ArrayList<String> scrollString;
	private ViewGroup baseCenterView;
	private KeyboardsView keyboardView;
	private Keyboard qwertyKeyboard;
	private Keyboard numericKeyboard;
	private Keyboard symbolsKeyboard;
	private Keyboard calculatorKeyboard;
	private IntentFilter filter;  
	protected KeyboardBroadcastReceiver breceiver=null;
	private Vibrator vibrator;
	private ContextUtils cUtils;
	
	PatternUtils pattern;
	//private Pattern p;
	
	//-- CALCULATOR
	String val1 = "";
	String val2 = "";
	String op = "";
	Boolean done = false;
	
	//------
	private Handler splitHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {

			super.handleMessage(msg);
			
			flag = true;
		}
	};
	
	private void processThread() {

		new Thread() {

			public void run() {

				scrollString = pattern.Split(currentText); 
				int i;
				for (i=0; i < scrollString.size(); i++){
					if (!scrollString.get(i).equals(" "))
						speechManager.sayPattern(scrollString.get(i), true, false);
					//Log.d(TAG, scrollString.size() + " scrollString[" + i + "]" + scrollString.get(i));
				}
				
				splitHandler.sendEmptyMessage(0);
			}
		}.start();
	}
	//----
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    
	    Log.d(TAG, "OnCreate");
    
	    configurationManager = ConfigurationManager.getInstance(getApplicationContext());
	    
	    // Metodo di BaseViewManager
	    Init(getBaseContext());

	    cUtils = new ContextUtils(this.getApplicationContext());
	    
	    numericKeyboard = new Keyboard(this, R.xml.numeric);
	    symbolsKeyboard = new Keyboard(this, R.xml.symbols);
	    calculatorKeyboard = new Keyboard(this, R.xml.calculator);
	    keyboardView = new KeyboardsView(this, null);
	    //keyboardView.setBackgroundResource(R.drawable.custom_keyboard);
	
	    
	    Intent intent = getIntent();
	    returnHere = intent.getStringExtra("whereReturn");
	    whichKeyboard = intent.getStringExtra("keyboardType");
	    if (whichKeyboard.equals("QWERTY_KEYBOARD")){
	    	Log.d(TAG, "QWERTY_KEYBOARD");
	    	qwertyKeyboard = new Keyboard(this, R.xml.qwerty);
	    	setKeyboard(qwertyKeyboard, R.string.K_Qwerty);
	    	messageToSay = cUtils.processString(intent.getStringExtra("messageToSay"));
	    }
	    
	    if (whichKeyboard.equals("QWERTY_KEYBOARD_NO_MODIFY")){
	    	Log.d(TAG, "QWERTY_KEYBOARD_NO_MODIFY");
	    	qwertyKeyboard = new Keyboard(this, R.xml.qwerty_no_modify);
	    	setKeyboard(qwertyKeyboard, R.string.K_Qwerty_No_Modify);
	    	messageToSay = cUtils.processString(intent.getStringExtra("messageToSay"));
	    }

	    if (whichKeyboard.equals("NUMERIC_KEYBOARD")){
	    	Log.d(TAG, "NUMERIC_KEYBOARD");
	    	setKeyboard(numericKeyboard, R.string.K_Numeric);
	    	messageToSay = cUtils.processString(intent.getStringExtra("messageToSay"));
	    }
	    
	    if (whichKeyboard.equals("CALCULATOR_KEYBOARD")){
	    	Log.d(TAG, "CALCULATOR_KEYBOARD");
	    	setKeyboard(calculatorKeyboard, R.string.K_Calculator);
	    }
   	    
	    pattern = new PatternUtils();
	    
	    getBaseView().setBackgroundColor(android.R.color.black);
        setContentView(getBaseView());
        
        baseCenterView = (ViewGroup) findViewById(R.id.center_base_view);
        baseCenterView.addView(keyboardView);
        keyboardView.setOnTouchListener(listener);
        //keyboardView.setBackgroundResource(R.drawable.custom_keyboard);
           
        filter=new IntentFilter();
        filter.addAction(GestureIntents.INTENT_GESTURE_KEYBOARD_CHOICE);
        filter.addAction(GestureIntents.INTENT_GESTURE_KEYBOARD_SELECTION);
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        
        breceiver=new KeyboardBroadcastReceiver();
        this.getBaseContext().registerReceiver(breceiver, filter);
 
	}
	
	@Override
	protected void onResume() {
		super.onResume();

		speechManager = SpeechManager.getInstance(getApplicationContext());

		if (!whichKeyboard.equals("CALCULATOR_KEYBOARD"))
			speechManager.say(messageToSay, true, false);

		vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();

		this.getBaseContext().unregisterReceiver(breceiver);	
		//getBaseView().setBackgroundColor(getResources().getColor(R.color.white2));
		Log.d(TAG, "onDestroy");
	}

	
	// BACK
	@Override
	public void onClick_A(){
		Log.d(TAG, "onClick_A");
		if (backTo == BACK_TO_QWERTY){
			setKeyboard(qwertyKeyboard, R.string.K_Qwerty);
			whichKeyboard = "QWERTY_KEYBOARD";
			backTo = 0;
		}else{
			Intent returnIntent;
			returnIntent=new Intent(returnHere);
			returnIntent.putExtra("Result", "NORESULT");
			returnIntent.addCategory(Intent.CATEGORY_DEFAULT);					
			sendBroadcast(returnIntent);
			sentResult = true;
			vibrator.vibrate(300);
			finish();	
		}
	}

	// POSITION
	@Override
	public void onClick_B(){
		Log.d(TAG, "onClick_B");
		vibrator.vibrate(100);
		if(position != null)
			speechManager.say(position, true, false);	
	}

	
	// REPEAT
	@Override
	public void onClick_C(){
		Log.d(TAG, "onClick_C");
		vibrator.vibrate(100);
				
		if (currentText == "" || currentText.length() == 0){ //if (scrollString.size() == 0){
			speechManager.say(getString(R.string.TTS_Empty), true, false);
			return;
		}	
		
		processThread();
	}
	
	
	//DONE
	@Override
	public void onClick_D(){
		Log.d(TAG, "onClick_D");

		if (whichKeyboard.equals("CALCULATOR_KEYBOARD"))
			onClick_A();
		else{
			if (backTo == BACK_TO_QWERTY){
				setKeyboard(qwertyKeyboard, R.string.K_Qwerty);
				whichKeyboard = "QWERTY_KEYBOARD";
				backTo = 0;
			}else{
				Intent returnIntent;
				returnIntent=new Intent(returnHere);
				returnIntent.putExtra("Result", currentText);
				returnIntent.addCategory(Intent.CATEGORY_DEFAULT);					
				sendBroadcast(returnIntent);
				sentResult = true;
				vibrator.vibrate(200);
				finish();
			}
		}
	}


	@Override
	public void onClick_Center(int event, float X, float Y){
		Log.d(TAG, "onClick_Center");
	
		keyboardView.setOffset(getOffset());
		keyboardView.handleEvent(event, X, Y);
	}
	
	private void setKeyboard(Keyboard k, int p){
		keyboardView.setKeyboard(k);
		position = getString(p);
	}
	
	private class KeyboardBroadcastReceiver extends BroadcastReceiver{
		@Override
		public void onReceive(Context arg0, Intent intent) {
			
			Log.d(TAG, "onReceive");

			String intentStr;
			String value=intent.getStringExtra(GestureIntents.INTENT_GESTURE_KEYBOARD_CHOICE_VALUE);

			Log.d(TAG, "Single value: " + value);

			if (value.length() == 0)
				return;

			intentStr=intent.getAction();
			if(intentStr.equals(GestureIntents.INTENT_GESTURE_KEYBOARD_SELECTION)){

				if(whichKeyboard.equals("NUMERIC_KEYBOARD")){

					String vibrType = configurationManager.getVibration();

					if (vibrType.equals(getString(R.string.TTS_Level1))){

						if (value.equals("5")){

							long[] pattern = {0, 100, 200, 100};
							vibrator.vibrate(pattern, -1);
						}else
							vibrator.vibrate(100);
						
					} else if (vibrType.equals(getString(R.string.TTS_Level2))){
						
						if (value.equals("5")){

							long[] pattern = {0, 100, 100, 100, 100, 100};
							vibrator.vibrate(pattern, -1);
							
						}else if (value.equals("1") || value.equals("3") || 
								value.equals("5") || value.equals("7") || value.equals("9")){
							
							long[] pattern = {0, 100, 200, 100};
							vibrator.vibrate(pattern, -1);
							
						}else 
							vibrator.vibrate(150);
					}
				}
				sayKey(value, "SELECT");	
				return;
			} 

			if(intentStr.equals(GestureIntents.INTENT_GESTURE_KEYBOARD_CHOICE)){

				vibrator.vibrate(100);

				if(whichKeyboard.equals("CALCULATOR_KEYBOARD")){
					Calculate(value);
					return;
				}

				if (!value.equals(getString(R.string.K_Space)))
					sayKey(value, "CHOICE");

				if(value.equals("DEL") && whichKeyboard.equals("QWERTY_KEYBOARD_NO_MODIFY")){
					currentText = "DEL CHAR";
					onClick_D();
					return;
				}

				if (value.equals("DEL ALL") || value.equals("DEL") 
						|| value.equals("MODIFY") || value.equals(getString(R.string.K_Space))){ 

					if	(currentText == null || currentText.equals("")){
						speechManager.say(getString(R.string.TTS_Empty), true, false);
						return;
					}

					if(value.equals("DEL ALL")){
						currentText = "";
						//scrollString.clear(); 

					}else if(value.equals("DEL")){
						speechManager.say(getString(R.string.TTS_Deleted), true, false);
						speechManager.sayPattern("" + currentText.charAt(currentText.length() - 1), true, false);
						currentText = currentText.substring(0,currentText.length()- 1);

					}else if (value.equals("MODIFY")){
						getBaseContext().unregisterReceiver(breceiver);
						scrollString = pattern.Split(currentText);
						Intent modifyI;
						modifyI=new Intent(ModifyText.INTENT_SHOW);					
						modifyI.addCategory(Intent.CATEGORY_DEFAULT);
						modifyI.putExtra("OriginalText", currentText);
						modifyI.putStringArrayListExtra("ScrollText", scrollString);
						startActivityForResult(modifyI, MODIFY_FLAG);
					}

					if (value.equals(getString(R.string.K_Space))){
						scrollString = pattern.Split(currentText);
						speechManager.say(scrollString.get(scrollString.size()-1), false, false);
						currentText += " ";	
					}
					return;
				}

				if (value.equals("123")){
					setKeyboard(numericKeyboard, R.string.K_Numeric);
					whichKeyboard = "NUMERIC_KEYBOARD";
					backTo = BACK_TO_QWERTY;
					
				}else if (value.equals(", ;")){
					setKeyboard(symbolsKeyboard, R.string.K_Symbols);
					whichKeyboard = "SYMBOLS_KEYBOARD";
					backTo = BACK_TO_QWERTY;
					
				}else{
					currentText += value;	
				}	
			}
		}	
	}

	protected void onActivityResult (int requestCode, int resultCode, Intent data) {
		getBaseContext().registerReceiver(breceiver, filter);
		if (requestCode == MODIFY_FLAG && resultCode == RESULT_OK) {
			scrollString = data.getStringArrayListExtra("ModifiedScrollText");
			currentText = data.getStringExtra("ModifiedText");
			Log.d(TAG, "onActivityResult " + currentText);
		}
	}

	private void sayKey(String value, String speed){

		if (value.equals("ABC")) 
			if (speed.equals("SELECT"))
				speechManager.say(getString(R.string.K_Qwerty), false, true);
			else
				speechManager.say(getString(R.string.K_Qwerty), true, false);
		else if (value.equals(".")) 
			if (speed.equals("SELECT"))
				speechManager.say(getString(R.string.K_Dot), false, true);
			else
				speechManager.say(getString(R.string.K_Dot), true, false);
		else if (value.equals(", ;"))
			if (speed.equals("SELECT"))
				speechManager.say(getString(R.string.K_Symbols), false, true);
			else
				speechManager.say(getString(R.string.K_Symbols), true, false);
		else if (value.equals("123"))
			if (speed.equals("SELECT"))
				speechManager.say(getString(R.string.K_Numeric), false, true);
			else
				speechManager.say(getString(R.string.K_Numeric), true, false);
		else if (value.equals("DEL"))
			if (speed.equals("SELECT"))
				speechManager.say(getString(R.string.K_Delete), false, true);
			else
				speechManager.say(getString(R.string.K_Delete), true, false);
		else if (value.equals("DEL ALL"))
			if (speed.equals("SELECT"))
				speechManager.say(getString(R.string.K_Delete_All), false, true);
			else
				speechManager.say(getString(R.string.K_Delete_All), true, false);
		else if (value.equals("MODIFY"))
			if (speed.equals("SELECT"))
				speechManager.say(getString(R.string.K_Modify), false, true);
			else
				speechManager.say(getString(R.string.K_Modify), true, false);
		else if (value.equals(getString(R.string.K_Space)))
			if (speed.equals("SELECT"))
				speechManager.say(getString(R.string.K_Space), false, true);
			else
				speechManager.say(getString(R.string.K_Space), true, false);
		else {
			if ((position.equals(getString(R.string.K_Symbols)) && 
					!value.equals(getString(R.string.K_Qwerty)) && 
					!value.equals(getString(R.string.K_Numeric))))
				if (speed.equals("SELECT"))
					speechManager.saySpecialChar(value, false, true);
				else
					speechManager.saySpecialChar(value, true, false);
			else{
				if (speed.equals("SELECT"))
					speechManager.say(value, false, true);
				else
					speechManager.say(value, true, false);
			}
		}
	}
	
	
	
	private String Calculate(String val){
		
		Float res = null;
		Float one, two;
			
		if (val.equals(getString(R.string.K_Delete))){
			
			Log.d(TAG, "Delete");
			scrollString.remove(scrollString.size()-1); 			
	
			if (val2.length() != 0)	{	
				val2 = val2.substring(0,val2.length()- 1);		
				return null;
			}
			if (op.length() != 0)	{	
				op = op.substring(0,op.length()- 1);		
				return null;
			}
			if (val1.length() != 0)	{	
				val1 = val1.substring(0,val1.length()- 1);		
				return null;
			}
		}	

		if (val.equals(getString(R.string.K_Delete_All))){		
			scrollString.clear();
			done = false;
			val1 = "";
			val2 = "";
			op = "";		
			return null;
		}

				
		if (MathUtils.isInteger(val) || val.equals(".")){

			scrollString.add(val);
		
			if (!done){
				Log.d(TAG, "NOT DONE");
				val1 += val;
			}else {
				Log.d(TAG, "DONE");
				val2 += val;
			}
			return null;		
		} 
		
		if (val.contains("=")){

			Log.d(TAG, "------------ " + val1 + " " + val2);
			
			if (val1.length() == 0 || val2.length() == 0){
				speechManager.say(getString(R.string.K_Missing_Op), true, false);
				return null;
			}
			one = new Float(val1);
			two = new Float(val2);
			
			if (op.equals("+")){		
				res = one + two;

			}else if (op.equals("-")){
				res = one - two;

			}else if (op.equals("*")){
				res = one * two;

			}else if (op.equals("/")){
				if (!val2.equals("0"))
					res = one / two;
			}
			if (val.equals("="))
				speechManager.say(res.toString(), true, false);
			
			scrollString.clear(); 
			done = false;
			val1 = "";
			val2 = "";
			op = "";
			return res.toString();
		}	

		scrollString.add(val);
		if (op.length() != 0)
			val1 = Calculate("==");
		op = val;
		done = true;	

		return null;
	}	
}
